package com.zy.email.test;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.util.Date;
import java.util.Properties;

/**
 * User: 11473
 * Date: 2019/10/22
 * Time: 15:31
 * Description: 发送邮件
 */
public class emailUtil {

    /**
     * 发送邮件的账号
     */
    static String senderAddress = "1147364218@qq.com";

    /**
     * 发送邮件的 密码  or   授权码
     *  QQ邮箱授权码 efqrvbanpadebace
     *  网易163授权码 zy1147364218
     */
    static String passWord = "efqrvbanpadebace";

    /**
     * 服务器的地址
     * QQ邮箱地址 smtp.qq.com
     * 网易163地址 smtp.163.com
     */
    static String emailAccout = "smtp.qq.com";


    /**
     * 发送邮件
     * @param addresseeAddress  收件人邮箱地址
     * @param name  收件人名
     * @param subject   邮件主题
     * @param text  发送的文本
     * @throws Exception
     */
    public static void sendEmail(String addresseeAddress,String name,String subject,String text) throws Exception {

        Properties properties = new Properties();
        //设置传输模式为smtp模式
        properties.setProperty("mail.transport.protocol","smtp");
        //设置发送人邮件服务器的smtp地址
        properties.setProperty("mail.smtp.host", emailAccout);
        //设置验证机制
        properties.setProperty("mail.smtp.auth", "true");

        // SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,
        // 需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,
        // QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
        final String smtpPort = "465";
        properties.setProperty("mail.smtp.port", smtpPort);
        properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.setProperty("mail.smtp.socketFactory.fallback", "false");
        properties.setProperty("mail.smtp.socketFactory.port", smtpPort);

        // 创建对象回话跟服务器交互
        Session session = Session.getInstance(properties);
        // 会话采用debug模式
        session.setDebug(true);
        // 创建邮件对象
        Message message = createSimpleImageMail(session,addresseeAddress,name,subject,text);

        Transport trans = session.getTransport();
        // 链接邮件服务器
        trans.connect(senderAddress, passWord);
        // 发送信息
        trans.sendMessage(message, message.getAllRecipients());
        // 关闭链接
        trans.close();
    }

    /**
     * 设置邮件的具体内容 --纯文本
     * @param session   session
     * @param addresseeAddress  收件人邮箱地址
     * @param name  收件人名
     * @param subject   邮件主题
     * @param text  发送的文本
     * @return
     * @throws Exception
     */
    public static Message createSimpleMail(Session session,String addresseeAddress,String name,String subject,String text) throws Exception {

        MimeMessage message = new MimeMessage(session);
        // 设置发送邮件地址,param1 代表发送地址 param2 代表发送的名称(任意的)(有用) param3 代表名称编码方式
        message.setFrom(new InternetAddress(senderAddress, "郑岩", "utf-8"));
        // 代表收件人personal
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(addresseeAddress, name, "utf-8"));
        // To: 增加收件人（可选）
        /*message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress("dd@receive.com", "USER_DD", "UTF-8"));
        // Cc: 抄送（可选）
        message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress("ee@receive.com", "USER_EE", "UTF-8"));
        // Bcc: 密送（可选）
        message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress("ff@receive.com", "USER_FF", "UTF-8"));*/
        // 设置邮件主题
        message.setSubject(subject);
        // 设置邮件内容
        message.setContent(text, "text/html;charset=utf-8");
        // 设置发送时间
        message.setSentDate(new Date());
        // 保存上面的编辑内容
        message.saveChanges();

        return message;
    }

    public static Message createSimpleImageMail(Session session,String addresseeAddress,String name,String subject,String text) throws Exception {

        MimeMessage message = new MimeMessage(session);
        // 设置发送邮件地址,param1 代表发送地址 param2 代表发送的名称(任意的)(有用) param3 代表名称编码方式
        message.setFrom(new InternetAddress(senderAddress, "郑岩qq", "utf-8"));
        // 代表收件人personal
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(addresseeAddress, name, "utf-8"));
        // To: 增加收件人（可选）
        /*message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress("dd@receive.com", "USER_DD", "UTF-8"));
        // Cc: 抄送（可选）
        message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress("ee@receive.com", "USER_EE", "UTF-8"));
        // Bcc: 密送（可选）
        message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress("ff@receive.com", "USER_FF", "UTF-8"));*/
        // 设置邮件主题
        message.setSubject(subject);

        // 创建图片"节点"
        MimeBodyPart image = new MimeBodyPart();
        // 读取本地文件
        DataHandler dh = new DataHandler(new FileDataSource("image.jpg"));
        // 将图片数据添加到"节点"
        image.setDataHandler(dh);
        // 为"节点"设置一个唯一编号（在文本"节点"将引用该ID）
        image.setContentID("mailTestPic");

        // 创建文本"节点"
        MimeBodyPart texts = new MimeBodyPart();
        // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
        texts.setContent("这是一张图片<br/><a href='#'><img src='cid:mailTestPic'/></a>", "text/html;charset=UTF-8");

        // （文本+图片）设置 文本 和 图片"节点"的关系（将 文本 和 图片"节点"合成一个混合"节点"）
        MimeMultipart mm_text_image = new MimeMultipart();
        mm_text_image.addBodyPart(texts);
        mm_text_image.addBodyPart(image);
        mm_text_image.setSubType("related");    // 关联关系

        // 将 文本+图片 的混合"节点"封装成一个普通"节点"
        // 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
        // 上面的 mailTestPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
        MimeBodyPart text_image = new MimeBodyPart();
        text_image.setContent(mm_text_image);

        //创建附件"节点"
        MimeBodyPart attachment = new MimeBodyPart();
        // 读取本地文件
        DataHandler dh2 = new DataHandler(new FileDataSource("邮件测试文件.txt"));
        // 将附件数据添加到"节点"
        attachment.setDataHandler(dh2);
        // 设置附件的文件名（需要编码）
        attachment.setFileName(MimeUtility.encodeText(dh2.getName()));

        //设置（文本+图片）和 附件 的关系（合成一个大的混合"节点" / Multipart ）
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text_image);
        mm.addBodyPart(attachment);     // 如果有多个附件，可以创建多个多次添加
        mm.setSubType("mixed");         // 混合关系


        // 设置邮件内容
        message.setContent(mm);
        // 设置发送时间
        message.setSentDate(new Date());
        // 保存上面的编辑内容
        message.saveChanges();

        return message;
    }

}
